<?php
namespace control;
/*
*委外发料单类
*/

class outsourcePickClass extends adIndexClass
{
	private const page    = 'outsourcePick';
	private const table   = 'outsource_pick_order';
	private const tableMx = 'outsource_pick_order_detail';
	private const title   = '委外发料单';

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => '单据编号',
                        'width' => 300,
                        'sort' => 1,
                    ],
                    'supplier' => [
                        'name'  => "委外单位",
                        'width' => 300,
                    ],
                    'pickId'  => [
                        'name'  => "发料人",
                        'width' => 200,
                    ],
                    'num'         => [
                        'name'  => '数量',
                        'width' => 200,
                    ],
                    'recordDate'          => [
                        'name'  => '单据日期',
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'state'          => [
                        'name'  => '状态',
                        'width' => 250,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据编号" => text(array("name" => "orderNo")),
                    "委外单位"   => selectMultiple(["name" => "supplierId", 'table' => "supplier", 'sqlId' => 'id', 'where' => "coid = '" . self::$coid . "' and outsource = '是'", 'sqlField' => 'name', 'class' => 'width200']),
                    '发料人' => text(array("name" => "pickId")),
                ],
                [
                    "单据日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    "状态" => select(["name" => "state", 'option' => ['草稿', '待确认', '已确认']]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

	/*列表-查询条件*/
	public function home()
	{
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        $isEdit = $this->power(self::page, "edit");
        if ($isEdit) {
            $button .= "<span onclick=\"newIframe('" . self::title . "详情','" . $url . "&fun=edit')\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        if ($this->power(self::page, "print")) {
            $button .= " <span onclick=\"batchPrint('" . $this->get('cla') . "')\" class='spanButton'>批量打印</span>\n";
        }
		//返回
		return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
	}

	/*客户列表-查询结果*/
	public function homeSearch()
	{
		//like查询数组
		$like = array(
			"orderNo" => $this->post('orderNo'),
			"pickId"  => $this->post('pickId'),
		);
		//全等查询数组
		$equal = array(
			"state" => $this->post('state'),

			'coid' => self::$coid,
		);
		$and   = " and type=0";
		if ($this->post('createTime')) {
			$and .= self::timeComparison($this->post('createTime'), 'date', 'recordDate');
		}
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'recordDate desc,time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
		//获取查询结果
		$where = search(array("like" => $like, "=" => $equal)) . $and;
		$page  = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
		//获取记录
		$url = root . "control/adIndex.html?cla=" . self::page;
		$isEdit = $this->power(self::page, "edit");
		foreach ($page['array'] as $array) {
			//列表控件
			$dominate = array(
				"box"    => array("name" => "listId", "value" => $array['id']),
				"edit"   => array("title" => "编辑", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=edit&id=" . $array['id'] . "')"),
				"detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
				'print'  => array('title' => '打印', 'click' => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$array['id']}')"),
				'track'  => array("title" => "单据追踪", "click" => "newIframe('单据追踪','" . root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=委外发料单&id=" . $array['id'] . "')"),
			);
			if ($array['state'] == '已确认' || !$isEdit) {
				unset($dominate['edit']);
			}
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "supplier":
                        $row[] = supplierClass::getName($array['supplierId']);
                        break;
                    case "num":
                        $num      = find(array('table' => self::tableMx, 'where' => "orderId = '$array[id]'", 'sum' => "num"));
                        $row[] = $num;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
		}
        $totalQuery = find([
            'table'  => self::tableMx,
            'single' => "orderId in (select id from ".self::table." where 1=1 {$where})",
            'field'  => "ifnull(sum(num),0) as num",
        ]);
        $total    = [
            'num'      => self::lostZero($totalQuery['num'],'numPrecision'),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
		//返回
		$json['html'] = "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
		return json_encode($json, 320);
	}
    /**
     * 保存并提交
     * @return bool|string
     */
    public function saveAndCommit(): bool|string
    {
        $resultJson = $this->editEdit();
        $result = json_decode($resultJson,true);
        if ($result['warn'] == 2){
            unset($_SESSION['warn']);
            $resultJson = $this->commitEdit();
        }
        return $resultJson;
    }
	/**
	 * 编辑页
	 *
	 * @return string
	 */
	public function edit(): string
	{
		$id   = $this->get('id');
		$info = query(self::table, " id = '" . $id . "' ");

		$button[] = [
			'style' => 'li-btn-blue-bg',
			"name"  => "保存",
			"type"  => "点击事件",
			"title" => "保存",
			'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')",
		];
        $button[] = [
            "name" => "保存并提交",
            "type" => "点击事件",
            "title" => "保存",
            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=saveAndCommit')"
        ];
		//仓库
		$result = find(array('table' => 'warehouse', 'field' => 'id,name', 'where' => "coid = '" . self::$coid . "' order by time desc"));
		$tr[]   = [
			'',
            '物料编码',
            '物料名称',
            '规格型号',
            '单位',
            '工序',
            "<div class='warehouse'><span class='word'>仓库</span>&emsp;" . self::chooseSelect($result['array'], 'warehouseId[]', 'warehouse') . "</div>",
			'数量',
            '当前可用库存',
            '关联委外加工单',
            '备注'
		];
		$result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
        $totalArr = ['num'=>0];
		foreach ($result['array'] as $k=>$array) {
			$material                 = query('material', " id = '$array[materialId]'");
			$outsource_process_detail = query('outsource_process_detail', "id = '$array[sourceId]'");
			$outsource_process        = query('outsource_process', "id = '$outsource_process_detail[orderId]'");
			//当前可用库存
			$inventoryNum = machiningOrderClass::inventory($array['materialId'], $array['unit'], $array['warehouseId']);
			$unitOption   = machiningOrderClass::unitOption($material['id']);
			$tr[]         = [
                componentClass::tablePperation($k+1,"delTableRow(this);calculateTotal()").
				hidden(array('name' => 'mxId[]', 'value' => $array['id'])) .
				hidden(array('name' => 'materialId[]', 'value' => $array['materialId'])) .
				hidden(array('name' => 'sourceId[]', 'value' => $array['sourceId'])),
				$material['code'],
				$material['name'],
				$material['model'],
				select(array('name' => 'unitDetail[]', 'data' => ['unit' => $array['unit']], 'change' => 'unitChange', 'option' => $unitOption, 'title' => '单位', 'value' => $array['unit'])),
                selectMultiple(array('name' => 'processId[]', 'title' => '工序', 'table' => 'process', 'where' => "state = '启用' and coid = '" . self::$coid . "' order by orderNo asc", 'sqlId' => 'id', 'sqlField' => 'name', 'value' => $array['processId'])),
				idSelect(array('name' => 'warehouseId[]', 'sqlForm' => "warehouse", 'change' => 'getInventory', 'sqlId' => 'id', 'sqlField' => "name", 'title' => '仓库', 'value' => $array['warehouseId'])),
				text(array('name' => 'num[]', 'blur' => 'calculateTotal', 'other' => self::digitalFiltering('numPrecision'), 'value' => self::lostZero($array['num'], 'numPrecision'))),
				"<span class='inventory'>" . self::formattingFigure($inventoryNum, 'numPrecision') . "</span>",
				$outsource_process['orderNo'],
				text(array('name' => 'mxText[]', 'class' => 'text textPrice', 'value' => $array['text'])),
			];
			$totalArr['num'] += $array['num'];
		}
        $total = [
            7=> "<span id='total_num'>".self::lostZero($totalArr['num'],'numPrecision')."</span>",
        ];
		$list  = $this->listTable(array('tr' => $tr, 'end' => true, 'total' => $total));
        $mxButton = <<<efo
                <span class="smallButton" onclick="chooseOrder('委外加工单')">关联委外加工单</span>
                <span class="smallButton" onclick="chooseOrder()">选择物料</span>
<!--                         <input id="barcode" style="margin-left: 20px" type="text" class="text" placeholder="输入或扫码"/>-->
<!--                         <label class="checkbox"><input id="cancel_button" type="checkbox" ><span></span>&nbsp;撤销</label>-->
efo;
		//表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . "委外单位：" => selectMultiple([
                        "name" => "supplierId",
                        'value' => $info['supplierId'],
                        'table' => "supplier",
                        'sqlId' => 'id',
                        'where' => "coid = '" . self::$coid . "' and outsource = '是'",
                        'sqlField' => 'name',
                        'title' => '请选择'
                    ]),
                    must . "发料人："   => text(["name" => "pickId", "value" => $info['pickId'] ?: $this->control['name']]),
                    must . "单据日期：" => text(["name" => "recordDate", 'laydate' => [], "value" => $info['recordDate'] ?: $this->date]),
                ],
                [
                    "备注："            => textarea(["name" => "text", "value" => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => '领料明细',
            'button' => $mxButton,
            'html' => $list,
        ]);
		$data['html'] = $this->pageEdit([
			"html"  => $body,
			'hidden' => hidden(['name' => 'id', 'value' => $id]),
		]);
		$data['html'] .= $this->js() . $this->style();
		//返回
		return $this->tab($data);
	}


	/**
	 * 根据条码获取属性ID
	 */
	public function getMaterial(): bool|string
	{
		if (empty($this->post('code'))) {
			$json['warn'] = "未找到条码";
		} else {
			$material  = query('material', "barcode = '" . $this->post('code') . "' and coid = '" . self::$coid . "'");
			$json['data'] = $material['id'];
			$json['warn'] = 2;
		}
		return json_encode($json, 320);
	}


	/**
	 * JS
	 *
	 * @return string
	 */
	public function js(): string
	{
		$cla = self::page;
		return <<<eof
<script>
function chooseOrder(type='') {
  let supplierId = $("[name='supplierId']").val();
  if (type=='委外加工单'){
      if (!supplierId){
          msg('请先选择委外单位','error')
          return false;
      }
      layer('{$this->get('cla')}','addOrder',$('form[name=outsourcePickEditForm]').serialize())
  }else{
      layer('{$this->get('cla')}','addMx',$('form[name=outsourcePickEditForm]').serialize())
  }
}
/***扫码操作***/
$("#barcode").on('keydown',function(event) {
    if (event.keyCode==13){
        let code = $(this).val();//条码
        if (!code){
            msg('未找到条码','error')
            return '';
        }
        //判断是否是撤销操作
        if ($("#cancel_button").is(":checked")){
            //撤销
            $.post(root+'control/adIndex.html?cla={$cla}&fun=getMaterial',{code:code},function(res) {
                  if (res.warn===2){
                      $("#materialTable").find("input[name='materialId[]']").each(function() {
                           if (res.data === $(this).val()){
                               $(this).parent().parent().remove();
                           }
                      });
                  }else{
                      msg(res.warn,'error');
                  }
            },'json')
        }else{
            //添加
             $.post(root+'control/adIndex.html?cla={$cla}&fun=getMaterial',{code:code},function(res) {
                 if (res.warn===2){
                       $.post(root+'control/adIndex.html?cla={$cla}&fun=addMxEdit',{materialId:res.data,classify:'barcode'},function(res) {
                           if (res.warn ==2){
                               $("#materialTable tbody").append(res.html);
                               resetNumber($("#materialTable"))
                           }else{
                               msg(res.warn,'error');
                           }
                           
                       },'json')
                  }else{
                      msg(res.warn,'error');
                  }
             },'json')
        }
    }
});

//获取当前可用库存
function getInventory(e){
    let obj = $(e).parent().parent();
    let warehouseId = e.value;
    let materialId = obj.find("[name='materialId[]']").val();
    let unit = obj.find("[name='unitDetail[]']").val();
    if (!warehouseId){
        msg('请选择仓库');
        obj.find(".inventory").html('');
    }else if(!materialId){
         msg('未找到物料');
        obj.find(".inventory").html('');
    }else if(!unit){
         msg('请选择单位');
        obj.find(".inventory").html('');
    }else{
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getInventory',{warehouseId:warehouseId,materialId:materialId,unit},function(res) {
              obj.find(".inventory").html(res.num);
        },'json');
    }
}
//根据单位转换所需数量和库存
function unitChange(e){
    let unit = e.value;
    if (!unit){
        msg('请选择单位')
        return '';
    }
    let oldUnit = $(e).data('unit');
    $(e).data('unit',unit);
    let num = $(e).parent().parent().find("[name='num[]']").val();
    let id = $(e).parent().parent().find("[name='materialId[]']").val();
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=unitChange',{unit:unit,oldUnit:oldUnit,num:num,id:id},function(res) {
        if (res.warn==2){
            $(e).parent().parent().find("[name='num[]']").val(res.num);
            $(e).parent().parent().find(".inventory").html(res.inventoryNum);
        }else{
            msg(res.warn);
        }
    },'json');
}

function addRow(classify = ''){
    if (classify === 'purchaseApply'){
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addOrderEdit',$("form[name='saleOrderForm']").serialize(),function(res) {
            $("#materialTable tbody").append(res.html);
            resetNumber($("#materialTable"))
        },'json');
    }else{
         $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMxEdit',$("form[name='mxForm']").serialize(),function(res) {
             if (res.warn ==2){
                $("#materialTable tbody").append(res.html);
                resetNumber($("#materialTable"))
           }else{
               msg(res.warn,'error');
           }
            
        },'json');
    }
}
//计算总金额，总税额
function calculateTotal(){
    let table = $('.editList')
    let num = 0
    table.find("[name='num[]']").each(function(index){
        if($(this).val()){
          num+=Number($(this).val());
        }
    })
    $("#total_num").text(num.toFixed(publicSettings.numPrecision.num));
}
</script>
eof;
	}


	/**
	 * 获取当前可用库存
	 */
	public function getInventory(): bool|string
	{
		$warehouseId   = $this->post('warehouseId');
		$materialId = $this->post('materialId');
		$unit          = $this->post('unit');
		//当前可用库存
		$inventoryNum = machiningOrderClass::inventory($materialId, $unit, $warehouseId);
		$json['num']  = self::formattingFigure($inventoryNum, 'numPrecision');
		return json_encode($json, 320);
	}

	/**
	 * 根据单位显示所需数量
	 */
	public function unitChange()
	{
		$materialId = $this->post('id');
		$num           = $this->post('num') ?: 0;
		$unit          = $this->post('unit');
		$oldUnit       = $this->post('oldUnit');
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑" . self::title . "的权限";
		} elseif (empty($materialId)) {
			$json['warn'] = '未找到物料';
		} elseif (empty($unit)) {
			$json['warn'] = '未找到单位';
		} else {
			$json['warn']         = 2;
			$inventoryNum         = machiningOrderClass::inventory($materialId, $unit);
			$json['num']          = $num;
			$json['inventoryNum'] = $inventoryNum;
			if ($oldUnit) {
				$num         = machiningOrderClass::material_num_change($materialId, $oldUnit, $unit, $num);
				$json['num'] = $num;
			}
		}

		return json_encode($json, 320);
	}

	/**
	 * 计算库存占用量
	 *
	 * @param $id string 委外发料单ID
	 * @param $warehouseId
	 * @param $materialId
	 * @param $unit
	 * @return float
	 */
	private function occupy($id, $warehouseId, $materialId, $unit): float
	{
		//未完全出库及未出库的领料总数量
		$outsourcePickMx = find(array(
		    'table' => "outsource_pick_order_detail as a join pick_order as b on a.orderId = b.id join inventory as c on c.sourceId = b.id",
            'where' => "b.state = '已确认' and b.type=0 and a.warehouseId = '$warehouseId' and a.coid = '" . self::$coid . "' and a.materialId = '$materialId' and c.state !='已出库' and b.id !='$id'",
            'field' => "a.num,a.unit"
        ));
		//每一个委外发料单明细单位都可能不同，所以需要统一为主单位再看需求是否需要转为其他单位
		$pickNum = 0;
		foreach ($outsourcePickMx['array'] as $array) {
			$pickNum += machiningOrderClass::material_num_change($materialId, $array['unit'], $unit, $array['num']);
		}
		//出库单中已出库的数量
		$outNum         = 0;
		$inventoryMxAll = find(array(
		    'table' => 'inventory_detail as a join inventory as b on a.orderId = b.id', 'field' => "a.num,a.unit",
            'where' => "b.state in ('待出库','部分出库')  and b.warehouseId = '$warehouseId' and a.coid = '" . self::$coid . "' and a.materialId = '$materialId' and b.classify=0 and b.sourceTable = '" . self::table . "'"
        ));
		foreach ($inventoryMxAll['array'] as $array) {
			$outNum += machiningOrderClass::material_num_change($materialId, $array['unit'], $unit, $array['num']);
		}
		return self::formattingFigure($pickNum - $outNum, 'numPrecision');
	}

	public function editEdit()
	{
		$id               = $this->post('id') ?: self::getId();
		$mxIdArr          = $this->post('mxId') ?: [];
		$materialIdArr = $this->post('materialId');
		$sourceIdArr      = $this->post('sourceId');
		$numArr           = $this->post('num');
		$unitArr          = $this->post('unitDetail');
		$processArr       = $this->post('processId');
		$mxTextArr        = $this->post('mxText');
		$warehouseIdArr   = $this->post('warehouseId');

		$field      = [
			'text'       => $this->post('text'),
			'supplierId' => $this->post('supplierId'),
			'pickId'     => $this->post('pickId'),
			'recordDate' => $this->post('recordDate'),
		];
		$annotation = [
			'supplierId' => '委外单位',
			'pickId'     => '发料人',
			'recordDate' => '单据日期',
		];
		$rules      = [
			'supplierId' => 'required',
			'pickId'     => 'required',
			'recordDate' => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$where = " id = '$id' ";
		$info  = query(self::table, $where);
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑" . self::title . "的权限";
		} elseif (static::is_null_array($mxIdArr)) {
			$json['warn'] = '请选择领料明细';
		} elseif (static::is_null_array($materialIdArr)) {
			$json['warn'] = '请选择领料明细';
		} elseif (static::is_null_array($numArr)) {
			$json['warn'] = '数量请填写完整';
		} elseif (static::is_null_array($unitArr)) {
			$json['warn'] = '请选择单位';
		} elseif (static::is_null_array($warehouseIdArr)) {
			$json['warn'] = '请选择仓库';
		} elseif (!empty($info['id']) && $info['state'] == '已确认') {
			$json['warn'] = '此委外发料单已确认，不能修改';
		} else {
			$json['warn'] = '';
			//选项控制
			if (optionSettingClass::getSettingItem('委外', 'outsourceStrictPick')) {
				//判断
				foreach ($mxIdArr as $index => $mxId) {
					if (isset($sourceIdArr[$index]) && static::total(array('table' => 'outsource_process_detail', 'where' => "id = '$sourceIdArr[$index]'")) > 0) {
						//此委外加工单所需物料总数量
						$outsource_process_detail = query('outsource_process_detail', "id = '$sourceIdArr[$index]'");
						//已领料数量
						$num     = 0;
						$pickAll = find(array('table' => 'outsource_pick_order_detail', "where" => "sourceId = '$sourceIdArr[$index]' and id !='$mxId' and coid = '" . self::$coid . "'"));
						foreach ($pickAll['array'] as $array) {
							$num += machiningOrderClass::material_num_change($array['materialId'], $array['unit'], $outsource_process_detail['unit'], $array['num']);
						}
						if (self::formattingFigure($num + $numArr[$index], 'numPrecision') > self::formattingFigure($outsource_process_detail['quantity'], 'numPrecision')) {
							$material     = query('material', "id = '$outsource_process_detail[materialId]'");
							$json['warn'] = "物料【{$material['name']}】的数量已超出委外加工单所需物料总数量";
							break;
						}
					}
				}
			}

			if (empty($json['warn'])) {
				$this->startTrans();
				$isPass = true;//事务通过标志
				if (!$info['id']) {
					$userNo       = codeTemplateClass::generateCode(self::page, [
						'prefix' => 'WWFL' . date('Ymd', strtotime($field['recordDate'])),
						'table'  => self::table,
						'field'  => 'orderNo',
						'where'  => "and coid = '" . self::$coid . "'",
					], $field);
					$field        = array_merge($field, [
						'id'      => $id,
						'orderNo' => $userNo,
						'state'   => '草稿',
						'coid'    => self::$coid,
						'stid'    => $this->control['stid'],
						'time'    => $this->time,
					]);
					$json['warn'] = static::insert(["table" => self::table, "field" => $field]);
				} else {
					$json['warn'] = static::update([
						"table" => self::table,
						"field" => $field,
						"where" => $where,
					]);
				}

				//添加或更新明细
				if (is_array($mxIdArr)) {
					foreach ($mxIdArr as $k => $nid) {
						$mx          = query(self::tableMx, "id = '$nid'");
						$numArr[$k]  = self::formattingFigure($numArr[$k], 'numPrecision');
						if (!empty($mx['id'])) {
							//更新
							$warn = static::update([
								"table" => self::tableMx,
								"field" => [
									'sourceId'      => $sourceIdArr[$k],
									'materialId'    => $materialIdArr[$k],
									'num'           => $numArr[$k],
									'unit'          => $unitArr[$k],
									'processId'     => $processArr[$k],
									'warehouseId'   => $warehouseIdArr[$k],
									'text'          => $mxTextArr[$k],
								],
								"where" => " id = '$nid'",
							]);
						} else {
							//新增
							$warn = static::insert([
								"table" => self::tableMx,
								"field" => [
									'id'            => $nid,
									'orderId'       => $id,
									'coid'          => self::$coid,
									'sourceId'      => $sourceIdArr[$k],
									'sourceTable'   => $sourceIdArr[$k] ? 'outsource_process_detail' : '',
                                    'materialId'    => $materialIdArr[$k],
									'num'           => $numArr[$k],
									'unit'          => $unitArr[$k],
                                    'processId'     => $processArr[$k],
									'warehouseId'   => $warehouseIdArr[$k],
									'text'          => $mxTextArr[$k],
								],

							]);
						}
						if (!in_array($warn, ['新增成功', '更新成功'])) {
							$isPass       = false;
							$json['warn'] = $warn;
							break;
						}
					}
				}

				if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
					$this->commitTrans();
					delete(array('table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"));
					if ($json['warn'] == '新增成功') {
						auditClass::operateRecord($id, '委外发料单', '新建');
					}
					//添加日志
					$type = mb_substr($json['warn'], 0, 2, 'utf-8');
					$text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
					$this->logText(["type" => self::page, "text" => $text]);
					//返回
					$_SESSION['warn'] = $json['warn'];
					$json['warn']     = 2;
					$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
				} else {
					$this->rollback();
				}
			}
		}

		resp:
		return json_encode($json, 320);
	}

	/**
	 * 关联委外加工单
	 *
	 * @return bool|string
	 */
	public function addOrder(): bool|string
	{
        $layerId          = $this->get('cla') . ucwords($this->get('fun'));
		$html   =
			text(array("name" => "orderNo", "title" => "委外加工单号")) .
			text(array("name" => "code", "title" => "物料编码")) .
			text(array("name" => "name", "title" => "物料名称")) .
			text(array("name" => "recordDate", 'class' => 'width200', 'laydate' => ['type' => 'date', 'range' => '~'], "title" => "单据日期-单据日期")) .
			hidden(array('name' => 'id', 'value' => $this->post('id'))) .
			hidden(array('name' => 'supplierId', 'value' => $this->post('supplierId'))) .
			hidden(array('name' => 'sourceId', 'value' => $this->post('sourceId') ? implode(',', $this->post('sourceId')) : ''));
		$button = "<input onclick=\"addRow('purchaseApply');$('#" . $layerId . "').remove()\" type='button' class='searchSub m-l-5' value='提交'>";
		$html   = $this->search($html);
		return $this->layer(array("title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
	}

	/**
	 * 关联委外加工单
	 *
	 * @return bool|string
	 */
	public function addOrderSearch(): bool|string
	{
		$sourceId = $this->post('sourceId') ? explode(',', $this->post('sourceId')) : [];
		$where    = " a.coid='" . self::$coid . "'  and b.id not in ('" . implode("','", $sourceId) . "')";
		$and      = " and a.isClose = 0";
		$like     = [
			'a.orderNo' => $this->post('orderNo'),
		];
		$equal    = [
			'supplierId' => $this->post('supplierId'),
			'a.state'    => '已确认',
		];
		if ($this->post('recordDate')) {
			//单据日期
			$and .= self::timeComparison($this->post('recordDate'), field: 'recordDate');
		}
		$where .= search(["like" => $like, "=" => $equal]) . $and;
		$page  = $this->page([
			"table"   => "outsource_process as a join outsource_process_detail as b on a.id  = b.orderId join material as c on b.materialId = c.id",
			"where"   => $where,
			'pageNum' => 50,
			"order"   => "a.recordDate desc,a.orderNo desc",
			'field'   => "b.*,a.orderNo,a.recordDate,a.supplierId,c.name,c.code,c.model",
		]);
		//获取表头
		$checkAll = $this->checkAll("saleOrderForm", "saleOrderId");
		$tr[]     = [$checkAll, '委外加工单号', '单据日期', '委外单位', '产品编码', '产品名称', '规格型号', '单位'];
		//获取记录
		foreach ($page['array'] as $array) {
			$dominate    = array(
				"box" => array("name" => "saleOrderId", "value" => $array['id']),
			);
			$tr[]        = array(
				$this->dominate($dominate),
				$array['orderNo'],
				$array['recordDate'],
				supplierClass::getName($array['supplierId']),
				$array['code'],
				$array['name'],
				$array['model'],
				$array['unit'],
			);
		}
		$json['html'] = $page['hint'] .
            "<form name='saleOrderForm'>" .
                hidden(array('name' => 'id', 'value' => $this->post('id'))) .
                $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) .
            "</form>" .
            $page['button'];
		return json_encode($json, 320);
	}

	/**
	 * 关联委外加工单
	 */
	public function addOrderEdit()
	{
		$id      = $this->post('id');
		$mxIdArr = $this->post('saleOrderId');
		if (!$this->power(self::page, 'edit')) {
			$json['warn'] = '你还没有编辑权限';
		} elseif (static::is_null_array($mxIdArr)) {
			$json['warn'] = '请选择委外加工单';
		} else {
			$tr           = [];
			foreach ($mxIdArr as $machiningOrderMxId) {
				$machiningOrderMx = query('outsource_process_detail', "id = '$machiningOrderMxId'");
				$machiningOrder   = query('outsource_process', "id = '$machiningOrderMx[orderId]'");
				$material         = query('material', "id = '$machiningOrderMx[materialId]'");
				$unitOption       = machiningOrderClass::unitOption($material['id']);
				//单位选项
				$select = select(array(
				    'name' => 'unitDetail[]',
                    'data' => ['unit' => $machiningOrderMx['unit']],
                    'change' => 'unitChange',
                    'option' => $unitOption,
                    'title' => '单位',
                    'value' => $machiningOrderMx['unit']
                ));
				//仓库选项
				$warehouse            = idSelect(array(
				    'name' => 'warehouseId[]',
                    'change' => 'getInventory',
                    'sqlForm' => "warehouse where coid = '" . self::$coid . "' order by time desc",
                    'sqlId' => 'id',
                    'sqlField' => "name",
                    'title' => '仓库'
                ));
				$pick_order_detailAll = find(array(
				    'table' => 'outsource_pick_order_detail',
                    'where' => "orderId !='$id' and sourceId = '$machiningOrderMx[id]' and coid = '" . self::$coid . "' and materialId = '$material[id]'"
                ));
				$orderNum             = 0;//已进进入委外发料单的委外加工单明细数量
				foreach ($pick_order_detailAll['array'] as $array) {
					$orderNum += machiningOrderClass::material_num_change($material['id'], $array['unit'], $machiningOrderMx['unit'], $array['num']);
				}
				$num  = ($machiningOrderMx['quantity'] - $orderNum) > 0 ? self::formattingFigure($machiningOrderMx['quantity'] - $orderNum, 'numPrecision') : 0;
				$tr[] = [
                    componentClass::tablePperation('',"delTableRow(this);calculateTotal()").
					hidden(array('name' => 'mxId[]', 'value' => suiji())) .
					hidden(array('name' => 'materialId[]', 'value' => $machiningOrderMx['materialId'])) .
					hidden(array('name' => 'sourceId[]', 'value' => $machiningOrderMx['id'])),
					$material['code'],
					$material['name'],
					$material['model'],
					$select,
                    selectMultiple(array(
                        'name' => 'processId[]',
                        'title' => '工序',
                        'table' => 'process',
                        'where' => "state = '启用' and coid = '" . self::$coid . "' order by orderNo asc",
                        'sqlId' => 'id',
                        'sqlField' => 'name',
                        'value' => $machiningOrderMx['processId']
                    )),
					$warehouse,
					text(array('name' => 'num[]', 'blur' => 'calculateTotal', 'other' => self::digitalFiltering('numPrecision'), 'value' => self::lostZero($num, 'numPrecision'))),
					"<span class='inventory'>0</span>",
					$machiningOrder['orderNo'],
					text(array('name' => 'mxText[]', 'class' => 'text textPrice')),
				];
			}
			$json['warn'] = 2;
			$json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
		}
		return json_encode($json, 320);
	}


	/**
	 * @return bool|string
	 */
	public function addMx()
	{
        $materialClassObj = new materialClass();
        $layerId          = $this->get('cla') . ucwords($this->get('fun'));
        $formName         = 'mxForm';
        $notAllowRepeat   = 1;
        $data             = [
            'sub'            => " onclick=\"addRow();$('#" . $layerId . "').remove()\" ",
            'continueAdding' => $notAllowRepeat ? " onclick=\"addRow();removeSelectedContent('" . $formName . "')\" " : " onclick=\"addRow();\" ",
            'hidden'         => hidden(["name" => "notAllowRepeat", "value" => $notAllowRepeat]) .
                hidden(["name" => "supplyControl", "value" => '允许委外']) .
                hidden(array('name' => 'materialId', 'value' => $this->post('materialId') ? implode(',', $this->post('materialId')) : '')),
        ];
        return $materialClassObj->addMx($data);
	}

	/**
	 * 编辑
	 *
	 * @return bool|string
	 */
	public function addMxEdit()
	{
		$mxIdArr       = $this->post('mxId');
		$materialId = $this->post('materialId');
		$classify      = $this->post('classify');//扫码添加类型
		if (!$this->power(self::page, 'edit')) {
			$json['warn'] = '你还没有编辑权限';
		} elseif ($classify !== 'barcode' && (empty($mxIdArr) || !is_array($mxIdArr))) {
			$json['warn'] = '请选择物料';
		} elseif ($classify === 'barcode' && empty($materialId)) {
			$json['warn'] = '未找到物料';
		} else {
			$json['html'] = '';
			if ($classify === 'barcode') {
				$mxIdArr[] = $materialId;
			}
            $tr=[];
			foreach ($mxIdArr as $mxId) {
				$material    = query('material', "id = '$mxId'");
				$unitOption  = machiningOrderClass::unitOption($material['id']);
				$select      = select(array(
				    'name' => 'unitDetail[]',
                    'data' => ['unit' => $material['unit']],
                    'change' => 'unitChange',
                    'option' => $unitOption,
                    'title' => '单位',
                    'value' => $material['unit']
                ));
				//仓库选项
				$warehouse = idSelect(array(
				    'name' => 'warehouseId[]',
                    'change' => 'getInventory',
                    'sqlForm' => "warehouse where coid = '" . self::$coid . "' order by time desc",
                    'sqlId' => 'id',
                    'sqlField' => "name",
                    'title' => '仓库'
                ));
				$tr[]      = [
                    componentClass::tablePperation('',"delTableRow(this);calculateTotal()").
					hidden(array('name' => 'mxId[]', 'value' => suiji())) .
					hidden(array('name' => 'materialId[]', 'value' => $mxId)) .
					hidden(array('name' => 'sourceId[]')),
					$material['code'],
					$material['name'],
					$material['model'],
					$select,
                    selectMultiple(array(
                        'name' => 'processId[]',
                        'title' => '工序',
                        'table' => 'process',
                        'where' => "state = '启用' and coid = '" . self::$coid . "' order by orderNo asc",
                        'sqlId' => 'id',
                        'sqlField' => 'name',
                        'value' => ''
                    )),
					$warehouse,
					text(array('name' => 'num[]', 'blur' => 'calculateTotal', 'other' => self::digitalFiltering('numPrecision'))),
					"<span class='inventory'>0</span>",
					'',
					text(array('name' => 'mxText[]', 'class' => 'text textPrice')),
				];
			}
			$json['warn'] = 2;
			$json['html'] = $this->tableMany(['tr'=>$tr,'thead'=>false]);
		}
		return json_encode($json, 320);
	}


	/*详情页*/
	public function detail(): string
	{
		$info = query(self::table, " id = '{$this->get('id')}'");
		if (empty($info['id'])) {
			$html = '未找到此' . self::title;
		} else {
			//菜单
			$data = array(
				"id" => $info['id'],
			);

			$button = [];
			if ($info['state'] == '草稿') {
				//按钮
				$button[] = [
					"name"  => "提交",
					"type"  => "弹出层",
					"cla"   => $this->get('cla'),
					"fun"   => "operate",
					"post"  => ["act" => 'commit', "id" => $info['id']],
					'style' => 'li-btn-blue-bg',
				];
			}
			if ($info['state'] != '已确认') {
				if ($this->power(self::page, "edit")) {
					//按钮
					$button[] = [
						"name"  => "编辑",
						"type"  => "顶部页卡",
						"title" => "编辑用户",
						"url"   => $this->root . "control/adIndex.html?cla={$this->get('cla')}&fun=edit&id=" . $info['id'],

					];
				}

				if ($this->power(self::page, "del")) {
					//按钮
					$button[] = [
						"name" => "删除",
						"type" => "弹出层",
						"cla"  => $this->get('cla'),
						"fun"  => "operate",
						"post" => ["act" => 'del', "id" => $info['id']],
					];
				}
			}
			//按钮
			$button[] = [
				"name" => "打印",
				"type" => "点击事件",
				"fun"  => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$info['id']}')",
			];

			if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
				$button[] = [
					"name"  => "确认",
					"type"  => "弹出层",
					"cla"   => $this->get('cla'),
					"fun"   => "operate",
					"post"  => ["act" => 'confirm', "id" => $info['id']],
					'style' => 'li-btn-blue-bg',
				];
			}
			if ($this->power(self::page, "confirm") && $info['state'] == '已确认') {
				$button[] = [
					"name" => "撤回",
					"type" => "弹出层",
					"cla"  => $this->get('cla'),
					"fun"  => "operate",
					"post" => ["act" => 'cancel', "id" => $info['id']],
				];
			}

			$button[] = [
				"name"  => "单据追踪",
				"type"  => "顶部页卡",
				"title" => "单据追踪",
				"url"   => $this->root . "control/adIndex.html?cla=orderTrack&fun=home&orderType=委外发料单&id=" . $info['id'],
			];
			//操作记录
            $button[] = self::operateLogBut($info['id']);

			$tr[]   = [
				'物料编码', '物料名称', '规格型号', '单位', '工序', "仓库", '数量', '当前可用库存', '关联委外加工单', '备注',
			];
			$result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
			$totalArr = ['num'=>0];
			foreach ($result['array'] as $array) {
				$material                 = query('material', " id = '$array[materialId]'");
				$outsource_process_detail = query('outsource_process_detail', "id = '$array[sourceId]'");
				$outsource_process        = query('outsource_process', "id = '$outsource_process_detail[orderId]'");
				//当前可用库存
				$inventoryNum = machiningOrderClass::inventory($array['materialId'], $array['unit'], $array['warehouseId']);
                $process    = query('process', "id = '$array[processId]'");
				$tr[]         = [
					$material['code'],
					$material['name'],
					$material['model'],
					$array['unit'],
                    $process['name'],
					warehouseClass::getName($array['warehouseId']),
					self::lostZero($array['num'], 'numPrecision'),
					$inventoryNum,
					$outsource_process['orderNo'],
					$array['text'],
				];
                $totalArr['num'] += $array['num'];
			}
            $total_tr = [
                6 => self::lostZero($totalArr['num'], 'numPrecision'),
            ];
			$supplier = query('supplier', "id = '$info[supplierId]'");
			//生成表单
            $data['button'] = $this->tableShowButton($button);
			$data['html'] = $this->tableShow(array(
                "基本信息" => array(
					array(
						"委外单位" => $supplier['name'],
						"发料人"   => $info['pickId'],
						"单据日期" => $info['recordDate'],
                        "单据编号" => $info['orderNo'],
					),
                    array(
                        "制单人"   => self::findStaff($info['stid']),
                        "状态"     => $info['state']
                    ),
					array(
						"备注" => pre($info['text']),
					),
				)
			));
            $data['html'] .= $this->detailList([
                'title' => '领料明细',
                'html' => $this->listTable(array('tr' => $tr, 'showEmpty' => true, 'showSort' => true, 'total' => $total_tr)),
            ]);
			//生成页面
			$html = $this->tab($data);
		}
		//返回
		return $html;
	}

	/**
	 * 确认
	 */
	public function confirmEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " id = '$id'");
		$field = [
			'state'       => '已确认',
			'checkId'     => self::$stid,
			'confirmTime' => $this->time,
		];

		$result = find(array('table' => self::tableMx, "where" => "orderId = '$id' order by list asc"));
		$warn   = '';
		//库存可用量控制
		$inventorySetting = optionSettingClass::getSetting('库存');
		if (isset($inventorySetting['inventoryCtrl']['option']) && $inventorySetting['inventoryCtrl']['option'] && in_array('inventoryOrder', (array)$inventorySetting['inventoryCtrl']['val'])) {
			//判断库存是否可领料
			foreach ($result['array'] as $array) {
				//当前可用库存
				$inventoryNum = machiningOrderClass::inventory($array['materialId'], $array['unit'], $array['warehouseId']);
				if ($array['num'] > $inventoryNum) {
					$material    = query('material', "id = '$array[materialId]'", "name");
					$warn        = "物料【{$material['name']}】领料数量已超出可用库存数量";
					break;
				}
			}
		}

		if (!$this->power(self::page, 'confirm')) {
			$json['warn'] = '你还没有确认权限';
		} elseif (empty($info['id'])) {
			$json['warn'] = '未找到此委外发料单';
		} elseif ($info['state'] != '待确认') {
			$json['warn'] = '此委外发料单不是待确认状态，不能确认';
		} elseif ($warn) {
			$json['warn'] = $warn;
		} else {
			$this->startTrans();
			$json['warn'] = update(array(
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			));
			$bool         = $this->insertInventory($info);
			if ($bool !== true) {
				$json['warn'] = $bool;
			}
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
				$this->commitTrans();
				auditClass::operateRecord($info['id'], '委外发料单', '确认');
				//添加日志
				$type = mb_substr($json['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$_SESSION['warn'] = $json['warn'];
				$json['warn']     = 2;
				$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
			} else {
				$this->rollback();
			}
		}
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 撤回
	 */
	public function cancelEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " id = '$id'");
		$field = [
			'state'       => '草稿',
			'checkId'     => '',
			'confirmTime' => '',
		];
		if (!$this->power(self::page, 'cancel')) {
			$json['warn'] = '你还没有撤回权限';
		} elseif (empty($info['id'])) {
			$json['warn'] = '未找到此委外发料单';
		} elseif ($info['state'] != '已确认') {
			$json['warn'] = '此委外发料单不是已确认状态，无需撤回';
		} elseif (static::total(array('table' => 'inventory', "where" => "sourceId = '$info[id]' and coid = '" . self::$coid . "' and state in ('部分出库','已出库')")) > 0) {
			$json['warn'] = '此委外发料单已存在有出库的单据，不能撤回';
		} else {
			$json['warn'] = update(array(
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			));
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $all = find(['table'=>self::tableMx,'where'=>"orderId = '$info[id]' and processId !='' order by list"]);
                foreach ($all['array'] as $array){
                    processInventoryClass::delData($array['id']);
                }
				//删除出库单
				delete(array('table' => 'inventory_detail', 'where' => "orderId in (select id from inventory where sourceId = '$info[id]' and coid = '" . self::$coid . "')"));
				delete(array('table' => 'inventory', 'where' => "sourceId = '$info[id]'"));
				auditClass::operateRecord($info['id'], '委外发料单', '撤回');
				//添加日志
				$type = mb_substr($json['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$_SESSION['warn'] = $json['warn'];
				$json['warn']     = 2;
				$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
			}
		}
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 提交
	 */
	public function commitEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " id = '$id'");
		$field = [
			'state' => '待确认',
		];
		if (!$this->power(self::page, 'edit')) {
			$json['warn'] = '你还没有编辑权限';
		} elseif (empty($info['id'])) {
			$json['warn'] = '未找到此委外发料单';
		} elseif ($info['state'] != '草稿') {
			$json['warn'] = '此委外发料单不是草稿状态，不能提交';
		} else {
			$json['warn'] = update(array(
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			));
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
				auditClass::operateRecord($info['id'], '委外发料单', '提交');
				//添加日志
				$type = mb_substr($json['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$_SESSION['warn'] = $json['warn'];
				$json['warn']     = 2;
				$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
			}
		}
		resp:
		return json_encode($json, 320);
	}

	/**
	 * 生成出库单
	 */
	private function insertInventory($info): bool|string
	{
		$re_array = [];//根据仓库重新分组
		$result   = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"));
		foreach ($result['array'] as $array) {
			$re_array[$array['warehouseId']][] = $array['id'];
		}
		$supplier = query('supplier', "id = '$info[supplierId]'");
		$index    = 1;
		foreach ($re_array as $warehouseId => $array) {
			$id     = self::getId();
			$field  = [
				'id'               => $id,
				'type'             => '委外领料',
				'coid'             => self::$coid,
				'sourceTable'      => self::table,
				'sourceId'         => $info['id'],
				'warehouseId'      => $warehouseId,
				'targetId'         => $info['supplierId'],
				'classify'         => 0,
				'state'            => '待出库',
				'stid'             => self::$stid,
				'orderDate'        => $this->date,
				'sourceDate'       => $info['recordDate'],
				'sourceNo'         => $info['orderNo'],
				'sourceTargetName' => $supplier['name'],
			];
			$userNo = codeTemplateClass::generateCode('outStock', [
				'prefix' => 'KCCK' . date('Ymd'),
				'table'  => 'inventory',
				'field'  => 'orderNo',
				'where'  => " and coid = '" . self::$coid . "'",
				'index'  => $index,
			], $field);
			$index++;
			$field['orderNo'] = $userNo;
			$warn             = static::insert(array(
				'table' => 'inventory',
				'field' => $field,
			));
			if ($warn != '新增成功') {
				return "出库单新建失败";
			}
			foreach ($array as $mxId) {
				$mx   = query(self::tableMx, "id = '$mxId'");
                $price = inventoryDefaultClass::pricingRules('outStockPrice', $mx['materialId'],$mx['unit']);
				$warn = static::insert(array(
					'table' => 'inventory_detail',
					'field' => [
						'id'            => self::getId(),
						'coid'          => self::$coid,
						'sourceTable'   => self::tableMx,
						'sourceId'      => $mx['id'],
						'materialId'    => $mx['materialId'],
						'unit'          => $mx['unit'],
						'orderId'       => $id,
						'orderNum'      => $mx['num'],
						'warehouseId'   => $mx['warehouseId'],
						'price'         => $price,
						'money'         => 0,
					],
				));
				if ($warn != '新增成功') {
					return "出库单明细新建失败";
				}
                //委外发料生成工序库存出库
				if($mx['processId']) {
                    processInventoryClass::iData([
                        'materialId' => $mx['materialId'],
                        'processId' => $mx['processId'],
                        'sourceId' => $mx['id'],
                        'num' => -$mx['num'],
                        'text' => "委外发料单【{$info['orderNo']}】",
                    ]);
                }
			}
		}
		return true;
	}

	// 操作中转
	public function operate()
	{
		$act  = $this->post('act') ?? '';
		$pwd  = $word = false; // 需要密码
		$form = $power = '';
		switch ($act) {
			case 'confirm':
				$act      = 'confirm';
				$msg      = '确认';
				$title    = '是否已确认此委外发料单，确认后将不可修改？';
				$function = 'confirmEdit';
				$form     = self::page . 'OperateForm, detailForm';
				$power    = '';
				$word     = true;
				break;
			case 'commit':
				$act      = 'edit';
				$msg      = '编辑';
				$title    = '是否确认提交此委外发料单？';
				$function = 'commitEdit';
				$form     = self::page . 'OperateForm, detailForm';
				$power    = '';
				$word     = true;
				break;
			case 'cancel':
				$act      = 'cancel';
				$msg      = '撤回';
				$title    = '是否确认撤回此委外发料单？';
				$function = 'cancelEdit';
				$form     = self::page . 'OperateForm, detailForm';
				$power    = '';
				$word     = true;
				break;
			default:
				$act      = 'del';
				$msg      = '删除' . self::title;
				$title    = self::page . 'Delete';
				$function = 'delete';
				$form     = self::page . 'OperateForm, listForm, quoForm';
				$power    = '';
				break;
		}
		if (!$this->power(self::page, $act)) {
			$_SESSION['warn'] = '你还没有' . $msg . '的权限';
			$json             = [
				'warn' => 2,
				'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
			];
		} else {
			return $this->confirm([
				'title'    => $title,
				'function' => $function,
				'form'     => $form,
				'power'    => $power,
				'pwd'      => $pwd,
				'word'     => $word,
			]);
		}

		resp:
		return json_encode($json, 320);
	}

	/**
	 * 删除
	 *
	 * @return bool|string
	 */
	public function delete()
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$json['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$json['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] == '已确认') {
					$warn = "删除失败：已确认，暂不能删除";
				} else {
					//最后删除基本参数
					delete(array("table" => self::table, "where" => " id = '$id' "));
					delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
					delete(array("table" => "auditing_follow", "where" => " typeId = '$id' "));
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(array("type" => self::page, "text" => $text));
			$_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$json['warn']     = 2;
			$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
		}
		return json_encode($json, 320);
	}

	/**
	 * 样式
	 *
	 * @return string
	 */
	public function style(): string
	{
		return <<<eof
<style>
.stateBlock{margin-top: 0}
.stateBlock ul li{padding: 2px 10px}
.footer-ul-parent{float: right;margin-right: 10px}
.footer-ul li{margin-top: 10px}
.table-top-title{
    height: 30px;
    line-height: 30px;
    font-size: 14px;
    margin-top: 20px;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}
</style>
eof;
	}


	/**
	 * 批量打印
	 *
	 * @return string
	 */
	public function batchPrint(): string
	{
		$lists = $this->get('lists');
		if (empty($lists)) {
			exit('参数错误');
		} else {
			$listId = base64_decode($lists, true);
			$array  = explode(',', $listId);
			$data   = [];
			foreach ($array as $id) {
				$data[] = static::printPage($id, false);
			}
			return (new printTemplateClass())->start(self::page, $data);
		}
	}

	/**
	 * 打印
	 *
	 * @return string
	 */
	public function printPage($param = '', $isReturn = true): string|array
	{
		$id                   = $param ?: $this->get('id');
		$info                 = query(self::table, " id = '$id'");
		$info['companyName']  = query('company', "coid = '" . self::$coid . "'")['name']; //公司名称
		$info['title']        = self::title;
		$info['printTime']    = $this->time;
		$info['stid']         = self::findStaff($info['stid']);
		$info['supplierName'] = query('supplier', "id = '$info[supplierId]'")['name'];
		$info['qr']           = "source=" . self::table . "&id=" . $info['id'];
		$detail               = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"])['array'];
		$items                = [];
		$x                    = 1;
		$totalNum             = 0;
		foreach ($detail as $array) {
			$material    = query('material', "id = '$array[materialId]'");
			$warehouse   = query('warehouse', "id = '$array[warehouseId]'");
			$items[]     = [
				'no'              => $x,
				'materialCode'    => $material['code'],
				'materialName'    => $material['name'],
				'warehouse'       => $warehouse['name'],
				'model'           => $material['model'],
				'unit'            => $material['unit'],
				'num'             => self::lostZero($array['num'], 'numPrecision'),
				'text'            => $array['text'],
			];
			$x++;
			$totalNum += $array['num'];
		}
		$append         = [
			'no'  => '合计',
			'num' => self::lostZero($totalNum, 'numPrecision'),
		];
		$items[]        = $append;
		$info['detail'] = $items;
		if ($isReturn) {
			return (new printTemplateClass())->start(self::page, $info);
		} else {
			return $info;
		}
	}
}

